/***************************************************************************
 $ @Description: 
 $ @Author: NavyPeng
 $ @Date: 2024-04-18 13:25:43
 $ @LastEditTime: 2024-04-19 15:13:33
 $ @LastEditors: NavyPeng
 ***************************************************************************/
#include "Ctrl.h"	

#if	VisitorPattern_

#include<list>

class ConcreteElementA;
class ConcreteElementB;


class  Visitor
{
private:
	string m_typeName;
public :
	Visitor(string _typeName) { m_typeName = _typeName; }
	virtual void VisitConcreteElementA(ConcreteElementA* concreteElementA) = 0;
	virtual void VisitConcreteElementB(ConcreteElementB* concreteElementB) = 0;
	string GetTypeName() { return m_typeName; }
};

// Element类， 定义一个Accept操作，它以一个访问者为参数
class Element
{
private:
	string m_typeName;
public:
	Element(string _typeName) { m_typeName = _typeName; }
	virtual void Accept(Visitor* _visitor) = 0;
	string GetTypeName() { return m_typeName; }
};

class ConcreteElementA : public Element
{
public:
	ConcreteElementA() : Element("ConcreteElementA") {}
	void Accept(Visitor* _visitor) override {
		_visitor->VisitConcreteElementA(this);
	}
	// 其他的相关方法
	void OperationA() {}
};

class ConcreteElementB : public Element
{
public:
	ConcreteElementB() : Element("ConcreteElementB") {}
	void Accept(Visitor* _visitor) override {
		_visitor->VisitConcreteElementB(this);
	}
	// 其他的相关方法
	void OperationB() {}
};


class ConcreteVisitor1 : public Visitor
{
public:
	ConcreteVisitor1():Visitor("ConcreteVisitor1"){}
	void VisitConcreteElementA(ConcreteElementA* concreteElementA)override {
		cout << concreteElementA->GetTypeName() << "被" << this->GetTypeName() << "访问" << endl;
	}
	void VisitConcreteElementB(ConcreteElementB* concreteElementB)override {
		cout << concreteElementB->GetTypeName() << "被" << this->GetTypeName() << "访问" << endl;
	}
};

class ConcreteVisitor2 : public Visitor
{
public:
	ConcreteVisitor2() :Visitor("ConcreteVisitor2") {}
	void VisitConcreteElementA(ConcreteElementA* concreteElementA)override {
		cout << concreteElementA->GetTypeName() << "被" << this->GetTypeName() << "访问" << endl;
	}
	void VisitConcreteElementB(ConcreteElementB* concreteElementB)override {
		cout << concreteElementB->GetTypeName() << "被" << this->GetTypeName() << "访问" << endl;
	}
};



// 枚举它的元素，可以提供一个高层的接口以允许访问者访问它的元素
class ObjectStructure
{
private:
	list<Element*>* m_pListElements = new list<Element*>();
public:
	void Attach(Element* element) {
		m_pListElements->push_back(element);
	}
	void Detach(Element* element) {
		m_pListElements->remove(element);
	}
	void Accept(Visitor* visitor) {
		for (auto e = m_pListElements->begin(); e != m_pListElements->end(); e++) {
			(*e)->Accept(visitor);
		}
	}

};

int main() {
	ObjectStructure* pO = new ObjectStructure();
	pO->Attach(new ConcreteElementA());
	pO->Attach(new ConcreteElementB());

	ConcreteVisitor1* pCV1 = new ConcreteVisitor1();
	ConcreteVisitor2* pCV2 = new ConcreteVisitor2();

	pO->Accept(pCV1);
	pO->Accept(pCV2);


}



#endif